home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / imlib / xwdread.c < prev   
C/C++ Source or Header  |  1996-04-11  |  15KB  |  586 lines

  1. /* readxwd.c */
  2. /* This program is limited to X11 format XWD files */
  3. #include "filter.hpp"
  4. #include "system.h"
  5. #include "image.hpp"
  6. #include "palette.hpp"
  7. #include "event.hpp"
  8. #include "video.hpp"
  9. #include "dos.h"
  10. #include "main.hpp"
  11. #include <stdio.h>
  12. #include "macs.hpp"
  13. #include "image24.hpp"
  14.  
  15. #define MAXCOLORS 256  
  16. //#define MC(x) (((x)<3)==0)
  17. #define MC(x) (x!=0)
  18.  
  19. // the following table converts rgb to cym.
  20. int ca[8]={1,1,1,1,0,0,0,0},
  21.     ma[8]={1,0,1,0,1,0,1,0},
  22.     ya[8]={1,1,0,0,1,1,0,0};
  23. // the following defines make a color threshold
  24. #define RGB2C(r,g,b) (char)(ca[MC(b)|MC(g)<<1|MC(r)<<2])
  25. #define RGB2Y(r,g,b) (char)(ya[MC(b)|MC(g)<<1|MC(r)<<2])
  26. #define RGB2M(r,g,b) (char)(ma[MC(b)|MC(g)<<1|MC(r)<<2])
  27.  
  28. #define LSBFirst    0
  29. #define MSBFirst    1
  30.  
  31. #define XYBitmap    0
  32. #define XYPixmap    1
  33. #define ZPixmap        2
  34.  
  35. #define StaticGray    0
  36. #define GrayScale    1
  37. #define StaticColor    2
  38. #define PseudoColor    3
  39. #define TrueColor    4
  40. #define DirectColor    5
  41.  
  42. typedef unsigned long xwdval;
  43. #define X11WD_FILE_VERSION 7
  44. typedef struct {
  45.     xwdval header_size;        /* Size of the entire file header (bytes). */
  46.     xwdval file_version;    /* X11WD_FILE_VERSION */
  47.     xwdval pixmap_format;    /* Pixmap format */
  48.     xwdval pixmap_depth;    /* Pixmap depth */
  49.     xwdval pixmap_width;    /* Pixmap width */
  50.     xwdval pixmap_height;    /* Pixmap height */
  51.     xwdval xoffset;        /* Bitmap x offset */
  52.     xwdval byte_order;        /* MSBFirst, LSBFirst */
  53.     xwdval bitmap_unit;        /* Bitmap unit */
  54.     xwdval bitmap_bit_order;    /* MSBFirst, LSBFirst */
  55.     xwdval bitmap_pad;        /* Bitmap scanline pad */
  56.     xwdval bits_per_pixel;    /* Bits per pixel */
  57.     xwdval bytes_per_line;    /* Bytes per scanline */
  58.     xwdval visual_class;    /* Class of colormap */
  59.     xwdval red_mask;        /* Z red mask */
  60.     xwdval green_mask;        /* Z green mask */
  61.     xwdval blue_mask;        /* Z blue mask */
  62.     xwdval bits_per_rgb;    /* Log base 2 of distinct color values */
  63.     xwdval colormap_entries;    /* Number of entries in colormap */
  64.     xwdval ncolors;        /* Number of Color structures */
  65.     xwdval window_width;    /* Window width */
  66.     xwdval window_height;    /* Window height */
  67.     long window_x;        /* Window upper left X coordinate */
  68.     long window_y;        /* Window upper left Y coordinate */
  69.     xwdval window_bdrwidth;    /* Window border width */
  70.     } X11WDFileHeader;
  71.  
  72. typedef struct {
  73.     unsigned long pixel;
  74.     unsigned short red, green, blue;
  75.     char flags;            /* do_red, do_green, do_blue */
  76.     char pad;
  77.     } X11XColor;
  78.  
  79. image *getinit(FILE *file, palette *&pal, int *padrightP);
  80. void getimage(FILE *file,image *image, int pad);
  81. int getpixnum(FILE *file);
  82.  
  83.  
  84. image *readxwd(char *input_file,palette *&pal)
  85. //char *hdfpal,int *palsize,int *cols,int *rows)
  86. {
  87.   FILE *ifd;
  88.   int padright;
  89.   image *im;
  90. #ifdef __WINDOWS
  91.    HCURSOR OldCur;
  92.    OldCur=SetCursor(LoadCursor(0,IDC_WAIT)); // set the cursor to the hour glass
  93. #endif
  94.   /* open input file */
  95.   if (strcmp(input_file,"-") == 0)
  96.     ifd = stdin;
  97.   else
  98.     ifd = fopen(input_file,"rb");
  99.   /* get X info from file */
  100.   if (!ifd)
  101.   {
  102. #ifndef __WINDOWS    
  103.     printf("Unable to open %s\n"
  104.        "Get your story strait and try again.\n",input_file);
  105.     exit(0);
  106. #endif
  107.   }
  108.   im=getinit( ifd, pal, &padright);
  109. //cols, rows, &padright, palsize, hdfpal);
  110.  
  111.   /* alloc image array */
  112.  
  113.   /* fill image array */
  114.   getimage(ifd, im, padright);
  115. #ifdef __WINDOWS
  116.    SetCursor(OldCur); // set the cursor to the hour glass
  117. #endif
  118.  
  119.   return(im);
  120. }
  121.  
  122. int bits_per_item, bits_used, bit_shift, bits_per_pixel, pixel_mask;
  123. int bit_order, byte_swap;
  124. char buf[4];
  125. unsigned char *byteP;
  126. unsigned short *shortP;
  127. unsigned long *longP;
  128.  
  129.  
  130. int bs_int(int s);
  131. long bs_long(long s);
  132. short bs_short(short s );
  133.  
  134.  
  135. image *getinit(FILE *file, palette *&pal, int *padrightP)
  136. {
  137.   /* Assume X11 headers are larger than X10 ones. */
  138.   unsigned char header[sizeof(X11WDFileHeader)];
  139.   image *im;
  140.   X11WDFileHeader *h11P;
  141.   char junk[800];
  142.   int i, dummy1, dummy2, dummy3;
  143.   unsigned  short minred, maxred;
  144.   X11XColor x11col;
  145.  
  146.   h11P = (X11WDFileHeader *) header;
  147.  
  148.   if (fread(header,sizeof(*h11P),1,file) != 1 )
  149.     {
  150.       fprintf(stderr,"couldn't read X11 XWD file header");
  151.       exit(-1);
  152.     }
  153.   if ( h11P->file_version != X11WD_FILE_VERSION )
  154.     {
  155.       byte_swap = 1;
  156.       h11P->file_version = bltl(h11P->file_version);
  157.       if (h11P->file_version != X11WD_FILE_VERSION)
  158.       {
  159.         set_error(imINCORRECT_FILETYPE);
  160.         return NULL;
  161.       }
  162.  
  163.       h11P->header_size = bltl(h11P->header_size);
  164.       h11P->file_version = bltl(h11P->file_version);
  165.       h11P->pixmap_format = bltl(h11P->pixmap_format);
  166.       h11P->pixmap_depth = bltl(h11P->pixmap_depth);
  167.       h11P->pixmap_width = bltl(h11P->pixmap_width);
  168.       h11P->pixmap_height = bltl(h11P->pixmap_height);
  169.       h11P->xoffset =  bltl(h11P->xoffset);
  170.       h11P->byte_order =  bltl(h11P->byte_order);
  171.       h11P->bitmap_unit = bltl(h11P->bitmap_unit);
  172.       h11P->bitmap_bit_order = bltl(h11P->bitmap_bit_order);
  173.       h11P->bitmap_pad = bltl(h11P->bitmap_pad);
  174.       h11P->bits_per_pixel = bltl(h11P->bits_per_pixel);
  175.       h11P->bytes_per_line = bltl(h11P->bytes_per_line);
  176.       h11P->visual_class = bltl(h11P->visual_class);
  177.       h11P->red_mask = bltl(h11P->red_mask);
  178.       h11P->green_mask = bltl(h11P->green_mask);
  179.       h11P->blue_mask = bltl(h11P->blue_mask);
  180.       h11P->bits_per_rgb = bltl(h11P->bits_per_rgb);
  181.       h11P->colormap_entries = bltl(h11P->colormap_entries);
  182.       h11P->ncolors = bltl(h11P->ncolors);
  183.       h11P->window_width = bltl(h11P->window_width);
  184.       h11P->window_height = bltl(h11P->window_height);
  185.       h11P->window_x = bltl(h11P->window_x);
  186.       h11P->window_y = bltl(h11P->window_y);
  187.       h11P->window_bdrwidth = bltl(h11P->window_bdrwidth);
  188.     }
  189.  
  190.   if ( fread( junk, 1, h11P->header_size - sizeof(*h11P), file ) !=
  191.       h11P->header_size - sizeof(*h11P) )
  192.     {
  193.       fclose(file);
  194.       set_error(imFILE_CORRUPTED);
  195.       return NULL;
  196.     }
  197.  
  198.   /* Check whether we can handle this dump. */
  199.   if ( h11P->pixmap_depth > 8 )
  200.     {
  201.       fclose(file);
  202.       set_error(imNOT_SUPPORTED);
  203.       return NULL;
  204.     }
  205.   if ( h11P->bits_per_rgb > 8 )
  206.     {
  207.       fclose(file);
  208.       set_error(imNOT_SUPPORTED);
  209.       return NULL;
  210.     }
  211.   if ( h11P->ncolors > MAXCOLORS )
  212.     {
  213.       fclose(file);
  214.       set_error(imNOT_SUPPORTED);
  215.       return NULL;
  216.     }
  217.   if ( h11P->pixmap_format != ZPixmap )
  218.     {
  219.       fclose(file);
  220.       set_error(imNOT_SUPPORTED);
  221.       return NULL;
  222.     }
  223.   if ( h11P->bitmap_unit != 8 && h11P->bitmap_unit != 16 &&
  224.       h11P->bitmap_unit != 32 )
  225.     {
  226.       fclose(file);
  227.       set_error(imNOT_SUPPORTED);
  228.       return NULL;
  229.     }
  230.   im=new image(h11P->pixmap_width,h11P->pixmap_height);
  231.   pal=new palette(h11P->colormap_entries);
  232.   *padrightP = h11P->bytes_per_line * 8 / h11P->bits_per_pixel - im->width();
  233.  
  234. /*****************************************************************************/
  235.   /* Read X11 colormap. */
  236. minred = 65535;
  237. maxred = 0;
  238.   for ( i = 0; i < h11P->colormap_entries; i++ )
  239.     {
  240.       if ( fread( &x11col, sizeof(X11XColor), 1, file ) != 1 )
  241.     {
  242.           fclose(file);
  243.           set_error(imFILE_CORRUPTED);
  244.           delete pal;
  245.           return NULL;
  246.     }
  247.     else
  248.     {
  249.       x11col.pixel=bltl(x11col.pixel);
  250.       x11col.red=bstl(x11col.red);
  251.       x11col.green=bstl(x11col.green);
  252.       x11col.blue=bstl(x11col.blue);
  253.     }
  254.       if (x11col.pixel < 256)
  255.     {
  256.       if (minred > x11col.red) minred = x11col.red;
  257.       if (maxred < x11col.red) maxred = x11col.red;
  258.       dummy1 = (unsigned) x11col.red>>8;
  259.       dummy2 = (unsigned) x11col.green>>8;
  260.       dummy3 = (unsigned) x11col.blue>>8;
  261.       pal->set(i,dummy1,dummy2,dummy3);
  262.     }
  263.       else
  264.     {
  265.       fprintf(stderr,"pixel value outside of valid HDF palette\n");
  266.       exit(-1);
  267.     }
  268.     }
  269.   /* rest of stuff for getpixnum */
  270.   bits_per_item = h11P->bitmap_unit;
  271.   bits_used = bits_per_item;
  272.   bits_per_pixel = h11P->bits_per_pixel;
  273.   bit_order = h11P->bitmap_bit_order;
  274.   pixel_mask = ( 1 << bits_per_pixel ) - 1;
  275.  
  276.   byteP = (unsigned char *) buf;
  277.   shortP = (unsigned short *) buf;
  278.   longP = (unsigned long *) buf;
  279.   return im;
  280. }
  281.  
  282. void getimage(FILE *file,image *im,int pad)
  283. {
  284.   int i,j;
  285.   unsigned char *sl;
  286. #if BYTE_ORDER!=BIG_ENDIAN
  287.   printf("little guys\n");
  288. #endif
  289.   printf("getting image, bits_per_item = %d %d %d\n",bits_per_item,bits_used,bit_order==MSBFirst);
  290.   for (i=0; i<im->height(); i++)
  291.     {
  292.       sl=im->scan_line(i);
  293.       for (j=0; j<im->width(); j++)
  294.     sl[j]= getpixnum(file);
  295.  
  296.       for ( j = 0; j < pad; j++ )
  297.     getpixnum( file );
  298.     }
  299. }
  300.  
  301.  
  302. int getpixnum(FILE *file)
  303. {
  304.   int p;
  305.   if ( bits_used == bits_per_item )
  306.     {
  307.       if ( fread( buf, bits_per_item / 8, 1, file ) != 1 )
  308.     fprintf(stderr, "couldn't read bits" );
  309.       if ( byte_swap )
  310.     switch ( bits_per_item )
  311.       {
  312.       case 8:
  313.         break;
  314.  
  315.       case 16: *shortP=short_swap(*shortP); break;
  316.  
  317.       case 32: *longP=long_swap(*longP); break;
  318.  
  319.       default:
  320.         fprintf(stderr, "can't happen" );
  321.       }
  322.       bits_used = 0;
  323.  
  324. //      if ( bit_order == MSBFirst )
  325.     bit_shift = bits_per_item - bits_per_pixel;
  326. //      else
  327. //    bit_shift = 0;
  328.     }
  329.  
  330.   switch ( bits_per_item )
  331.     {
  332.     case 8:
  333.       p = ( *byteP >> bit_shift) & pixel_mask;
  334.       break;
  335.  
  336.     case 16:
  337.       p = ( *shortP >> bit_shift) & pixel_mask;
  338.       break;
  339.  
  340.     case 32:
  341.       p = ( *longP >> bit_shift) & pixel_mask;
  342.       break;
  343.  
  344.     default:
  345.       fprintf(stderr, "can't happen" );
  346.     }
  347.  
  348. //  if ( bit_order == MSBFirst )
  349.     bit_shift -= bits_per_pixel;
  350. //  else
  351. //    bit_shift += bits_per_pixel;
  352.   bits_used += bits_per_pixel;
  353.  
  354.   return p;
  355. }
  356.  
  357.  
  358. short bs_short(short s )
  359. {
  360.   short ss;
  361.   unsigned char *bp, t;
  362.  
  363.   ss = s;
  364.   bp = (unsigned char *) &ss;
  365.   t = bp[0];
  366.   bp[0] = bp[1];
  367.   bp[1] = t;
  368.   return ss;
  369. }
  370.  
  371. int bs_int(int i )
  372. {
  373.   int ii;
  374.   unsigned char *bp, t;
  375.  
  376.   ii = i;
  377.   bp = (unsigned char *) ⅈ
  378.   t = bp[0];
  379.   bp[0] = bp[3];
  380.   bp[3] = t;
  381.   t = bp[1];
  382.   bp[1] = bp[2];
  383.   bp[2] = t;
  384.   return ii;
  385. }
  386.  
  387. long bs_long(long l )
  388. {
  389.   return bs_int( l );
  390. }
  391.  
  392. struct BMP_header
  393. {
  394.   char id[2];
  395.   long filesize;
  396.   short reserved[2];
  397.   long headersize,infosize,width,height;
  398.   short biplanes,bits;
  399.   long bicompression, bisizeimage, bixpelspermeter, biypelspermeter,
  400.        biclrused,biclrimportant;
  401. } bmp;
  402.  
  403. int read_BMP_header(FILE *fp)
  404. {
  405.   if (!fread(&bmp.id,1,2,fp)) return 0;         // 2 0
  406.   bmp.filesize=read_long(fp);                   // 4 4
  407.   if (!fread(bmp.reserved,1,4,fp)) return 0;    // 4 8
  408.   bmp.headersize=read_long(fp);                 // 4 12
  409.   bmp.infosize=read_long(fp);                   // 4 16
  410.   bmp.width=read_long(fp);                      // 4 20
  411.   bmp.height=read_long(fp);                     // 4 24
  412.   bmp.biplanes=read_short(fp);                  // 2 26
  413.   bmp.bits=read_short(fp);                      // 2 28
  414.   bmp.bicompression=read_long(fp);              // 4 32
  415.   bmp.bisizeimage=read_long(fp);                // 4 36
  416.   bmp.bixpelspermeter=read_long(fp);            // 4 40
  417.   bmp.biypelspermeter=read_long(fp);            // 4 44
  418.   bmp.biclrused=read_long(fp);                  // 4 48
  419.   bmp.biclrimportant=read_long(fp);             // 4 52
  420.   return 1;
  421.   
  422. }
  423.  
  424.  
  425.  
  426.  
  427. int bmp_bits(char *filename)
  428. {
  429.   FILE *fp;
  430.   fp=fopen(filename,"rb");
  431.   if (!fp) return 0;
  432.   if (!read_BMP_header(fp)) return 0; 
  433.   fclose(fp);
  434.  
  435.   if (bmp.id[0]!='B' || bmp.id[1]!='M')  
  436.     return 0;
  437.   else return bmp.bits;
  438. }
  439.  
  440. image24 *read_bmp24(char *filename)
  441. {
  442.   image24 *im;
  443.   FILE *fp;
  444.   int i,j;
  445.   fp=fopen(filename,"rb");
  446.   if (!fp)
  447.     return NULL;
  448.   if (!read_BMP_header(fp)) return NULL;
  449.   
  450.   if (bmp.id[0]!='B' || bmp.id[1]!='M')  
  451.     return NULL;
  452.  
  453.   if (bmp.bits!=24)
  454.     return NULL;
  455.   
  456.   im=new image24((bmp.width+3)&(0xffffffff-3),
  457.          (bmp.height+3)&0xffffffff-3);
  458.   if (!im)
  459.     return NULL;
  460.   
  461.   unsigned char *sl;
  462.   int trailer=im->width()%4;
  463.   if (trailer==1) trailer=3;
  464.   else if (trailer==3) trailer=1;
  465.   uchar buf[9];
  466.   for (i=im->height();i;i--)
  467.   {
  468.     sl=im->scan_line(i-1);
  469.     for (j=0;j<im->width();j++)    
  470.     { 
  471.       fread(sl+2,1,1,fp);
  472.       fread(sl+1,1,1,fp);      
  473.       fread(sl,1,1,fp); 
  474.       sl+=3;  
  475.     }    
  476.     if (trailer)
  477.       fread(buf,trailer*3,1,fp);
  478.   }
  479.   fclose(fp);
  480.  
  481.   return im; 
  482. }
  483.  
  484. image *read_bmp(palette *&pal, char *filename)
  485. {
  486.   image *im;
  487.   FILE *fp;
  488.   unsigned char pal_quad[4];
  489.   char *scrap;
  490.   int bytes,i;
  491.   fp=fopen(filename,"rb");
  492.   if (!fp)
  493.     return NULL;
  494.  
  495.   if (!read_BMP_header(fp)) return NULL;
  496.   
  497.   if (bmp.id[0]!='B' || bmp.id[1]!='M')  
  498.     return NULL;
  499.  
  500.   if (bmp.bits!=8)
  501.     return NULL;
  502.   
  503.   im=new image((bmp.width+3)&(0xffffffff-3),
  504.          (bmp.height+3)&0xffffffff-3);
  505.  
  506.   if (!im)
  507.     return NULL;
  508.  
  509.   pal=new palette(256);
  510.   for (i=0;i<256;i++)
  511.   {
  512.     fread(pal_quad,1,4,fp);
  513.     pal->set(i,pal_quad[2],pal_quad[1],pal_quad[0]);
  514.   }
  515.   bytes=(im->width()+3)/4;
  516.   bytes*=4;
  517.   scrap=(char *)jmalloc(bytes,"xwd_read scrap");
  518.   for (i=im->height();i;i--)
  519.   {
  520.     fread(scrap,1,bytes,fp);
  521.     memcpy(im->scan_line(i-1),scrap,im->width());
  522.   }
  523.   jfree(scrap);
  524.   fclose(fp);
  525.   return im;
  526. }
  527.  
  528. int write_BMP_header(FILE *fp)
  529. {
  530.   if (!fwrite(&bmp.id,1,2,fp)) return 0;  
  531.   write_long(fp,bmp.filesize);  
  532.   if (!fwrite(bmp.reserved,1,4,fp)) return 0;   
  533.   write_long(fp,bmp.headersize);
  534.   write_long(fp,bmp.infosize);  
  535.   write_long(fp,bmp.width);
  536.   write_long(fp,bmp.height);
  537.   write_short(fp,bmp.biplanes);
  538.   write_short(fp,bmp.bits);
  539.   write_long(fp,bmp.bicompression);
  540.   write_long(fp,bmp.bisizeimage);
  541.   write_long(fp,bmp.bixpelspermeter);
  542.   write_long(fp,bmp.biypelspermeter);
  543.   write_long(fp,bmp.biclrused);
  544.   write_long(fp,bmp.biclrimportant);   
  545.   return 1;
  546.   
  547. }
  548.  
  549. void write_bmp(image *im, palette *pal, char *filename)
  550. {
  551.   FILE *fp;
  552.   int i,bytes;
  553.   unsigned char pal_quad[4];
  554.   fp=fopen(filename,"wb");
  555.   if (!fp)
  556.   { printf("Error : unable to open %s for writing!\n");
  557.     exit(0);
  558.   }
  559.   bytes=(im->width()+3)/4;
  560.   memset((char *)&bmp,0,sizeof(bmp));
  561.   memcpy(bmp.id,"BM",2);
  562.   bmp.width=im->width();
  563.   bmp.height=im->height();
  564.   bmp.bits=8;
  565.   bmp.infosize=0x28L;
  566.   bmp.biplanes=1;
  567.   bmp.headersize=1078;
  568.   bmp.filesize=bmp.headersize+bytes*im->height()*4;
  569.   bmp.bisizeimage=im->width()*im->height();
  570.   bmp.biclrused=256;
  571.   bmp.biclrimportant=256;
  572.   write_BMP_header(fp);
  573.   
  574.   pal_quad[3]=0;
  575.   for (i=0;i<256;i++)
  576.   {
  577.     pal->get(i,pal_quad[2],pal_quad[1],pal_quad[0]);
  578.     fwrite(pal_quad,1,4,fp);
  579.   }
  580.   for (i=im->height();i;i--)
  581.     fwrite(im->scan_line(i-1),1,bytes*4,fp);
  582.   fclose(fp);
  583. }
  584.  
  585.  
  586.